/* -----------------------------------------------------
 iCompose
 InstrumentalPlayer.m
 
 Created by Team: THE BEARD on 19/10/09.
 Members who contributed to this file:
 1. Ethan Holmes
 2. Bobby Luk
 3. Stephen Laughton
 
 List of changes to previous member:
 Version 1:
 Oct. 26, 2009 (Bobby)
 - Implemented play function that uses the AVAudioPlayer class from AVFoundation.framework
 Oct. 31 2009 (Bobby)
 - Edited the play function to take an array of Note objects
 Oct. 31 2009 (Ethan)
 - implemented Encode / Decode methods
 Nov. 1 2009 (Bobby)
 - Simplified the way the URL is generated for the sound file and made audioPlayer call its
 prepareToPlay function before playing
 Version 2:
 17 Nov, 2009 (Stephen)
 - Implemented delegate method. Allowing user to interact with the app while notes are playing back.
 
 Simon Fraser University, 2009.
 ----------------------------------------------------- */

#import "InstrumentPlayer.h"

@implementation InstrumentPlayer

@synthesize audioPlayers;

- (id)init {
	if (self = [super init]){
		audioPlayers = [[NSMutableArray alloc] initWithCapacity: 0];
	}
	return self;
}
/* 
 Precondition: Takes in the two inputs noteList, an NSMutableArray 
 of Note objects, and tempo, the Tempo object holding a value for 
 the speed of the musical piece.
 
 Postcondition: Plays a sound for each Note object in noteList for
 a duration of time based on the Tempo object's speed value.
 */
-(void)playNotes:(NSMutableArray*)noteList andTempo:(Tempo*)tempo {
	if([noteList count] == 0) {
		return;
	}
	
	// variables necesssary to play the sound
	float playTimeInSeconds;
	int pitch;
	int accidental;
	int finalPitch; // final pitch value after taking accidental into account
	NSString *noteNumber;
	NSString *path;
	
	NSLog(@"Calling InsturmentPlayer's method play.");
	
	// loop through the noteList while it still has Note objects
	while([noteList count] > 0) {
		// get the Note that is to be played
		NoteNode *nextNote = [noteList objectAtIndex:0];
		AVAudioPlayer *audioPlayer;
		
		// calculate the duration the note should be played in seconds
		// concept: beats * 1/(beats/minute) * 60 seconds/minute
		float speed = [tempo speed];
		playTimeInSeconds = nextNote.note.noteBeat * 1/speed * 60;
		if (nextNote.isNote) {
			// generate the audio file name that will be played
			pitch = nextNote.note.notePitch;
			NSLog(@"Playing note with pitch: %i", pitch);
			accidental = 0;
			finalPitch = pitch + accidental;
			noteNumber = [NSString stringWithFormat:@"%i", finalPitch];
		
			// initialize the audioPlayer
			path = [[NSBundle mainBundle] pathForResource:noteNumber ofType:@"mp3"];
			audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];
		}
		else if (nextNote.isRest) {
			path = [[NSBundle mainBundle] pathForResource:0 ofType:@"mp3"];
			audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];
		}
		
		// set the time to start at in the audio file and play it
		// ie. if playTimeInSeconds is x, then the following code will skip to the last x seconds of the audio file
		audioPlayer.currentTime = audioPlayer.duration - playTimeInSeconds;
		audioPlayer.delegate = self;
		[audioPlayer prepareToPlay];
		
		[audioPlayers addObject: audioPlayer];
		[noteList removeObjectAtIndex:0];
	}
	
	[[audioPlayers objectAtIndex: 0] play];
}

/*
 Stops whatever AVAudioPlayer is currently playing and clears list.
 */
- (void)stopNotes {
	if([audioPlayers count] != 0) {
		[[audioPlayers objectAtIndex:0] stop];
		[audioPlayers removeAllObjects];
	}
}

// Delegate method to start playing the next AVAudioPlayer in the array
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
	NSLog(@"finished playing note, starting new note");
    [player release];
	
	[audioPlayers removeObjectAtIndex:0];
	
	if ([audioPlayers count] > 0){
		[[audioPlayers objectAtIndex:0] play];
	}
}

@end
